package core

import (
	"biliMiddleware/global"
	"biliMiddleware/model"
	"biliMiddleware/rediscli"
	"io/ioutil"
	"net"
	"net/http"
	"sync"
	"time"

	"github.com/tidwall/gjson"
	"golang.org/x/net/proxy"
)

func InfoGetH5Room(Data model.Task, proxyStr string, wg *sync.WaitGroup, UpTaskList *[]model.Task) {
	defer wg.Done()
	dialer, _ := proxy.SOCKS5("tcp", proxyStr, &proxy.Auth{User: "chxu10t", Password: "chxu10t"}, &net.Dialer{
		Timeout:   3 * time.Second,
		KeepAlive: 3 * time.Second,
	})
	transport := &http.Transport{
		Proxy:               nil,
		Dial:                dialer.Dial,
		TLSHandshakeTimeout: 3 * time.Second,
	}
	client := &http.Client{Transport: transport}
	req, _ := http.NewRequest("GET", "https://api.live.bilibili.com/xlive/web-room/v1/index/getH5InfoByRoom", nil)
	param := req.URL.Query()
	param.Set("room_id", Data.RoomID)
	req.URL.RawQuery = param.Encode()
	resp, err := client.Do(req)
	if err != nil {
		global.Log.Errorf("func:InfoGetH5Room -> room_id:%v  proxyStr:%v  err:%v\n", Data.RoomID, proxyStr, err)
		return
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		global.Log.Errorf("func:InfoGetH5Room -> room_id:%v   err:%v\n", Data.RoomID, err)
		return
	}
	if resp.StatusCode != 200 {
		global.Log.Errorf("func:InfoGetH5Room -> room_id:%v   code:%v   body:%v\n", Data.RoomID, resp.StatusCode, string(body))
		return
	}
	Data.AnchorName = gjson.Get(string(body), "data.anchor_info.base_info.uname").String()
	roomInfo := gjson.Get(string(body), "data.room_info")
	Data.RealRoomID = roomInfo.Get("room_id").String()
	*Data.RoomStatus = roomInfo.Get("live_status").Int()
	*Data.OnLine = roomInfo.Get("online").Int()
	if *Data.RoomStatus == 1 {
		Data = FlvPlayURL(Data, proxyStr)
	} else {
		*Data.OnLine = 0
		Data.Durl = ""
		*Data.RoomStatus = 0
	}
	*UpTaskList = append(*UpTaskList, Data)
}

//FlvPlayURL ...获取视频源地址
func FlvPlayURL(Data model.Task, proxyStr string) model.Task {
	req, _ := http.NewRequest("GET", "https://api.live.bilibili.com/xlive/web-room/v1/playUrl/playUrl", nil)
	param := req.URL.Query()
	param.Set("cid", Data.RealRoomID)
	param.Set("platform", "web")
	param.Set("otype", "json")
	param.Set("quality", "0")
	param.Set("qn", "80")
	req.URL.RawQuery = param.Encode()
	dialer, _ := proxy.SOCKS5("tcp", proxyStr, &proxy.Auth{User: "chxu10t", Password: "chxu10t"}, &net.Dialer{
		Timeout:   3 * time.Second,
		KeepAlive: 3 * time.Second,
	})
	transport := &http.Transport{
		Proxy:               nil,
		Dial:                dialer.Dial,
		TLSHandshakeTimeout: 3 * time.Second,
	}
	client := &http.Client{Transport: transport}
	resp, err := client.Do(req)
	if err != nil {
		global.Log.Errorf("func:FlvPlayURL -> room_id:%v   err:%v\n", Data.RoomID, err)
		return Data
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		global.Log.Errorf("func:FlvPlayURL -> room_id:%v   err:%v\n", Data.RoomID, err)
		return Data
	}
	if resp.StatusCode != 200 {
		global.Log.Errorf("func:FlvPlayURL -> room_id:%v   code:%v   body%v\n", Data.RoomID, resp.StatusCode, string(body))
		return Data
	}
	dataJSON := gjson.Get(string(body), "data")
	qualityDescription := dataJSON.Get("quality_description").Array()
	description := qualityDescription[len(qualityDescription)-1]
	*Data.VideoLevel = description.Get("qn").Int()
	str := ""
	for _, k := range dataJSON.Get("durl").Array() {
		u := k.Get("url").String()
		if len(u) > 10 {
			str = str + u + "----"
		}
	}
	Data.Durl = str
	return Data
}

func CheckProxy(proxyChan <-chan string, wg *sync.WaitGroup) {
	defer wg.Done()
	for proxyStr := range proxyChan {
		dialer, _ := proxy.SOCKS5("tcp", proxyStr, &proxy.Auth{User: "chxu10t", Password: "chxu10t"}, &net.Dialer{
			Timeout:   3 * time.Second,
			KeepAlive: 3 * time.Second,
		})
		transport := &http.Transport{
			Proxy:               nil,
			Dial:                dialer.Dial,
			TLSHandshakeTimeout: 3 * time.Second,
		}
		client := &http.Client{Transport: transport}
		req, _ := http.NewRequest("GET", "https://api.live.bilibili.com/xlive/web-room/v1/index/getIpInfo", nil)
		response, err := client.Do(req)
		if err != nil {
			//global.Log.Errorf("func:CheckProxy ->client.Do(req)   proxyStr:%v   err:%v\n", proxyStr, err)
			return
		}
		defer response.Body.Close()
		_, err = ioutil.ReadAll(response.Body)
		if err != nil {
			//global.Log.Errorf("func:CheckProxy -> ioutil.ReadAll(response.Body)   err:%v\n", err)
			return
		}
		rediscli.SetProxyStr(proxyStr)
		return
	}
}
